/**
 * Copyright (c) 2011 Technical Centre Radio Systems Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ua.tcrs.tabula.config;

import java.io.IOException;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.File;
import java.util.Map;
import java.util.LinkedHashMap;

import ua.tcrs.tabula.util.Iterables;
import ua.tcrs.tabula.util.Predicates;

/** 
 * 
 */

public class FileCachedConfiguration extends MapConfiguration implements SavableConfiguration {
	private File file;
	public FileCachedConfiguration( String filename ) throws IOException {
		super( new MapCreator() {
			public Map<String,Section> createSectionsMap() { return new LinkedHashMap<String,Section>(); }
			public Map<String,String> createEntriesMap() { return new LinkedHashMap<String,String>(); }
		} );
		file = new File( filename );
		
		if ( file.exists() ) load();
	}
	protected void load() throws IOException {
		BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream( file ) ) );
		String line;
		Section sect = null;
		String lastkey = "";
		while ( (line = reader.readLine()) != null ) {
			line = line.trim();
			if ( line.length() == 0 || line.charAt(0) == '#' ) continue;
			if ( line.length() > 1 && line.charAt(0) == '[' && line.charAt(line.length()-1) == ']' ) { // section
				sect = section( line.substring( 1, line.length()-1 ) );
				lastkey = "";
			} else {
				if ( sect == null ) sect = section( "" );
				int idx = line.indexOf( '=' );
				if ( idx > 0 ) { // key=value
					lastkey = line.substring( 0, idx );
					sect.setInternal( lastkey, line.substring( idx+1 ) );
				} else { // line continues previous value
					String value = sect.getInternal( lastkey );
					value = (value==null?"":value+'\n');
					sect.setInternal( lastkey, value+line );
				}
			}
		}
		reader.close();
	}
	public void save() throws IOException {
		BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file ) ) );
		// save "" section first
		if ( Iterables.any( sections(), Predicates.equalTo("") ) ) {
			saveSection( writer, section( "" ) );
		}
		// save other sections
		for ( String sect: sections() ) {
			if ( !sect.equals("") ) {
				writer.append('[').append(sect).append("]\n");
				saveSection( writer, section( sect ) );
			}
		}
		writer.close();
	}
	protected void saveSection( BufferedWriter writer, Section sect ) throws IOException {
		// save "" key first
		String value = sect.getInternal( "" );
		if ( value != null ) writer.append( value ).append('\n');
		// save other keys
		for ( String key: sect.keys() ) {
			if ( !key.equals("") ) {
				writer.append(key).append('=').append(sect.getInternal(key)).append('\n');
			}
		}
	}
}

